/**
 * System:      oshys
 * Model:       log
 * Licence:     GNU General Public License v3
 * Author:      sunwl
 * Date:        2010/02/19
 */
package org.oshys.util.logging;

import java.text.MessageFormat;

/**
 * Logger。<br>
 * Logging模块的主要类。负责生成一个Logger并提供各个级别的输出方法。<br>
 * eg:<br>
 * &nbsp;&nbsp;Logger log = Logger.getLogger("my Logger");
 * &nbsp;&nbsp;log.debug("debug message");
 * &nbsp;&nbsp;log.trace("trace message");
 * 
 * @author sunwl
 */
public class Logger {

    private String name = null;

    private Logger logger = null;

    private AppenderChain<IAppender> appenderChain = new AppenderChain<IAppender>();
    /**
     * 构造方法，一般不应该调用这个构造方法，而应该使用下面提供的getLogger()方法。<br>
     * 如果确实需要自行组装Logger，那么应该至少在实例化Logger以后调用addAppender()方法指定Appender。
     * @param name
     */
    protected Logger(String name) {
        this.name = name;
    }
    /**
     * 获取一个Logger应该调用本方法。参数name随意。<br>
     * 但是name一般应该是使用Logger的类的类名。
     * @param name
     * @return
     */
    public static Logger getLogger(String name) {
        Logger logger = LogFactory.createLogger(name);
        logger.logger = logger;

        return logger;
    }
    /**
     * 获取一个Logger应该调用本方法。参数clazz随意。<br>
     * 但是clazz一般应该是使用Logger的类。这样，Logger的name域就是clazz的名称。
     * @param clazz
     * @return
     */
    public static Logger getLogger(Class clazz) {
        return getLogger(clazz.getName());
    }
    
    // 以下定义了从fatal到trace各个级别的输出消息的方法。
    //当需要输出错误栈时，应该使用参数带有Throwable的重载。

    public void fatal(Throwable thrown, String patternMsg, Object... args) {
        record(Level.FATAL, thrown, patternMsg, args);
    }

    public void error(Throwable thrown, String patternMsg, Object... args) {
        record(Level.ERROR, thrown, patternMsg, args);
    }

    public void warn(Throwable thrown, String patternMsg, Object... args) {
        record(Level.WARN, thrown, patternMsg, args);
    }

    public void debug(Throwable thrown, String patternMsg, Object... args) {
        record(Level.DEBUG, thrown, patternMsg, args);
    }

    public void info(Throwable thrown, String patternMsg, Object... args) {
        record(Level.INFO, thrown, patternMsg, args);
    }

    public void trace(Throwable thrown, String patternMsg, Object... args) {
        record(Level.TRACE, thrown, patternMsg, args);
    }

    public void fatal(String patternMsg, Object... args) {
        fatal(null, patternMsg, args);
    }

    public void error(String patternMsg, Object... args) {
        error(null, patternMsg, args);
    }

    public void warn(String patternMsg, Object... args) {
        warn(null, patternMsg, args);
    }

    public void debug(String patternMsg, Object... args) {
        debug(null, patternMsg, args);
    }

    public void info(String patternMsg, Object... args) {
        info(null, patternMsg, args);
    }

    public void trace(String patternMsg, Object... args) {
        trace(null, patternMsg, args);
    }

    protected void addAppender(IAppender val) {
        this.appenderChain.add(val);
    }

    protected AppenderChain<IAppender> getAllAppenders() {
        return this.appenderChain;
    }

    // private void record(Level level, Throwable thrown, String msg){
    // for(IAppender appender : this.appenderChain){
    // appender.append(new LogMessage(level, msg, thrown));
    // }
    // }
    /**
     * 输出消息的方法。
     * 注意：第三个参数patternMsg可以带有占位符号{n} n >= 0
     * @param level 
     * @param thrown 
     * @param patternMsg 消息，可以带有占位符{n} n >= 0
     * @param args 当patternMsg带有占位符时，该参数不应该被省略。
     */
    private void record(Level level, Throwable thrown, String patternMsg, Object... args) {
        // jvm��֤����args��Ϊ��
        if (patternMsg != null && args.length > 0) {
            patternMsg = MessageFormat.format(patternMsg, args);
        }
        for (IAppender appender : this.appenderChain) {
            appender.append(new LogMessage(level, patternMsg, thrown));
        }
    }
}

